package cn.com.longfuinfo.wx.kit;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jfinal.kit.PathKit;
import com.jfinal.kit.StrKit;
import com.jfinal.weixin.sdk.api.ApiResult;
import com.jfinal.weixin.sdk.api.MediaApi;

import cn.com.longfuinfo.wx.util.ImageUtil;

public class CommonKit {
	
	private static final String UNKNOWN = "unknown";
	private static final String LOCALHOST = "0:0:0:0:0:0:0:1";
	private static final Logger logger =  LoggerFactory.getLogger(CommonKit.class);
	/**
	 * 根据请求获取客户端真实ip
	 * @param request
	 * @return
	 */
	public static String getClientIp(HttpServletRequest request){
		String ip = request.getHeader("x-forwarded-for");
		if(StrKit.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)){
			ip = request.getHeader("Proxy-Client-IP");
		}
		if(StrKit.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)){
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if(StrKit.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)){
			ip = request.getHeader("HTTP_CLIENT_IP");		
		}
		if(StrKit.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)){
			ip = request.getHeader("X_FORWARDED_FOR");		
		}
		if(StrKit.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)){
			ip = request.getRemoteAddr();
		}
		if(LOCALHOST.equals(ip)){
			return "127.0.0.1";
		}else{
			int index = ip.indexOf(",");
			if(index >= 0){
				ip = ip.split(",")[0];
			}
			return ip;
		}
	}
	
	/**
	 * 生成指定位数的随机数字
	 */
	public static String randomNum(int len){
		StringBuffer random = new StringBuffer(len);
		for(int i = 0; i < len; i++){
			random.append((int)(Math.random() * 10));
		}
		return random.toString();
	}
	
	/**
	 * 生成4位随机数字
	 */
	public static String randomNum(){
		return randomNum(4);
	}
	public static String randomNums(){
		return randomNum(10);
	}
	/**
	 * 获取UUID
	 */
	public static String getUUID(){
		String s = UUID.randomUUID().toString(); 
        //去掉“-”符号 
        return s.substring(0,8)+s.substring(9,13)+s.substring(14,18)+s.substring(19,23)+s.substring(24); 
	}
	
	/**
	 * 判断入参是否为空，如果为空，则返回空串，如果不为空，则返回本身，模仿oracle中的nvl函数，或mysql中的ifnull函数
	 */
	public static String ifNull(String value){
		return ifNull(value,"");
	}
	
	/**
	 * 判断入参是否为空，如果为空，则返回设定的串，如果不为空，则返回本身，模仿oracle中的nvl函数，或mysql中的ifnull函数
	 */
	public static String ifNull(String value,String nullStr){
		if(StrKit.isBlank(value)){
			return nullStr;
		}
		return value;
	}
	
	/**
	 * 将入参strs以字符串split为分隔进行拼接
	 */
	public static String join(String split,String... strs){
		if(strs!=null&&strs.length!=0){
			StringBuffer sBuffer = new StringBuffer();
			for(String str : strs){
				sBuffer.append(str).append(split);
			}
			sBuffer.deleteCharAt(sBuffer.length()-1);
			return sBuffer.toString();
		}
		return null;
	}
	
	public static String join(String split,int... ints){
		if(ints!=null&&ints.length!=0){
			StringBuffer sBuffer = new StringBuffer();
			for(int str : ints){
				sBuffer.append(str).append(split);
			}
			sBuffer.deleteCharAt(sBuffer.length()-1);
			return sBuffer.toString();
		}
		return null;
	}
	
	/**
	 * 密码加密
	 */
	public static String encryptPassword(String passwordStr){
		return DigestUtils.md5Hex(passwordStr);
	}
	
	/**
	 * 密码对比
	 */
	public static boolean passwordsMatch(String passwordStr, String encrypted){
		if(!StrKit.isBlank(passwordStr)&&!StrKit.isBlank(encrypted)){
			return encryptPassword(passwordStr).equalsIgnoreCase(encrypted);
		}
		return false;
	}
	
	/**
	 * 处理手机号码，隐藏中间四位数字
	 */
	public static String hideMsisdn(String msisdn){
		if(!StrKit.isBlank(msisdn)&&ValidateKit.Mobile(msisdn)){
			return msisdn.substring(0,3)+"****"+msisdn.substring(7);
		}
		return null;
	}
	
	 /**
     * 获取一定长度的随机字符串
     * @param length 指定字符串长度
     * @return 一定长度的字符串
     */
    public static String getRandomStringByLength(int length) {
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
    
    /**
     * url encode
     */
    public static String encodeURL(String src){
    	if(StrKit.isBlank(src)){
    		return "";
    	}
    	try {
    		return URLEncoder.encode(src, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
    	return src;
    }
    
    /**
     * 保存微信二维码
     */
    public static String saveWXQrcode(String qrcode_url, String ftpPath) throws Exception{
    	String filePath = "";
    	try {
			URL url = new URL(qrcode_url);
			logger.info(url.toString());
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5 * 1000);
			InputStream input = conn.getInputStream();
			byte[] data = readInputStream(input);
			String imgPath = PathKit.getWebRootPath() + "/upload" + System.currentTimeMillis() + ".jpg";
			File imageFile = new File(imgPath);
			logger.info(imageFile.toString());
			//创建输出流 
	        FileOutputStream outStream = new FileOutputStream(imageFile);
	        //写入数据 
	        outStream.write(data);
	        //关闭输出流
	        outStream.close();
	        File file = new File(imgPath);
	        //获取文件，并上传至FTP根目录下，用UUID重命名
	        String fileName = file.getName();
	        String extension = fileName.substring(fileName.lastIndexOf("."));
	        String newFileName = CommonKit.getUUID();
	        FTPClientKit.upload(ftpPath, newFileName + extension, file);
	        filePath = ftpPath + newFileName + extension;
	        logger.info(filePath.toString());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
    	return filePath;
    }
    /**
     * 保存微信二维码 并返回二维码ftp地址以及二维码图片对象
     */
    public static Map<String,Object> returnWXQrcode(String qrcode_url, String ftpPath) throws Exception{
    	logger.info("returnqrcode");
    	Map<String,Object> map = new HashMap<String, Object>();
    	String filePath = null;
    	File file = null;
    	try {
			URL url = new URL(qrcode_url);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5 * 1000);
			InputStream input = conn.getInputStream();
			byte[] data = readInputStream(input);
			String imgPath = PathKit.getWebRootPath() + "\\upload\\" + System.currentTimeMillis() + ".jpg";
			File imageFile = new File(imgPath);
			//创建输出流 
	        FileOutputStream outStream = new FileOutputStream(imageFile);
	        //写入数据 
	        outStream.write(data);
	        //关闭输出流
	        outStream.close();
	        //获取文件，并上传至FTP根目录下，用UUID重命名
	        file = new File(imgPath);
	        map.put("file", file);
	        String fileName = file.getName();
	        String extension = fileName.substring(fileName.lastIndexOf("."));
	        String newFileName = CommonKit.getUUID();
	        logger.info("upqrbe");
	        FTPClientKit.upload(ftpPath, newFileName + extension, file);
	        logger.info("upqraf");
	        filePath = ftpPath + newFileName + extension;
	        map.put("qrcodePath", filePath);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
    	return map;
    }
   /**
    * 生成并保存用户海报至ftp并返回海报地址
    * @param ftpPath 海报保存的ftp路径
    * @param file 	 生成海报的二维码文件对象
    * @return 
    */
    public static Map<String,Object> savePost(String ftpPath,File qrcode){
    	logger.info("savepost");
    	Map<String,Object> map = new HashMap<String,Object>();
    	ImageUtil util = new ImageUtil();
    	//将二维码文件缩放至一定比例(430*430-->283*283)
    	BufferedImage qrcodeIcon = util.scale(qrcode, 250, 250);
    	//设置二维码图片在海报声的拓印数据
		ImageUtil.setImageMarkOptions(0.8f,250,316,null,null);
		//获取海报背景图片的文件路径（固定）
		File file = new  File(PathKit.getWebRootPath()+"/static/app/img/erweima.png");
		logger.info("bj"+file.getPath());
		//获取文件上传的本地保存路径
		String imgPath = PathKit.getWebRootPath() + "/upload/" + System.currentTimeMillis() + ".jpg";
		logger.info("uploadpath"+imgPath);
		//将二维码拓印在海报背景图片上，并保存在本地。
		ImageUtil.markImageByIcon(qrcodeIcon, file, imgPath);
		logger.info("拓印");
		//获取文件，并上传至FTP根目录下，用UUID重命名
		File post = new File(imgPath);
		//将海报文件对象上传到微信永久素材库
		ApiResult result = MediaApi.addMaterial(post);
		logger.info("postpath"+post.getPath());
		//获取素材上传后微信返回的media_id
		String mediaId = result.getStr("media_id");
		logger.info("mediaid"+mediaId);
		map.put("mediaId", mediaId);
		String fileName = post.getName();
	    String extension = fileName.substring(fileName.lastIndexOf("."));
	    String newFileName = CommonKit.getUUID();
	    try {
			FTPClientKit.upload(ftpPath, newFileName + extension, post);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    String postFtpPath = ftpPath + newFileName + extension;
	    map.put("postFtpPath", postFtpPath);
    	
    	return map;
    }
    
    /**
     * 
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws Exception{  
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();  
        //创建一个Buffer字符串  
        byte[] buffer = new byte[1024];  
        //每次读取的字符串长度，如果为-1，代表全部读取完毕  
        int len = 0;  
        //使用一个输入流从buffer里把数据读取出来  
        while( (len=inStream.read(buffer)) != -1 ){  
            //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度  
            outStream.write(buffer, 0, len);  
        }  
        //关闭输入流  
        inStream.close();  
        //把outStream里的数据写入内存  
        return outStream.toByteArray();  
    } 
    /**
     * 过滤微信返回的用户信息中的用户名，清除特殊符号，以及表情图
     * @param source 需要处理的字符串
     */
    public static boolean containsEmoji(String source) {
        int len = source.length();
        boolean isEmoji = false;
        for (int i = 0; i < len; i++) {
            char hs = source.charAt(i);
            if (0xd800 <= hs && hs <= 0xdbff) {
                if (source.length() > 1) {
                    char ls = source.charAt(i + 1);
                    int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                    if (0x1d000 <= uc && uc <= 0x1f77f) {
                        return true;
                    }
                }
            } else {
                // non surrogate
                if (0x2100 <= hs && hs <= 0x27ff && hs != 0x263b) {
                    return true;
                } else if (0x2B05 <= hs && hs <= 0x2b07) {
                    return true;
                } else if (0x2934 <= hs && hs <= 0x2935) {
                    return true;
                } else if (0x3297 <= hs && hs <= 0x3299) {
                    return true;
                } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d
                        || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c
                        || hs == 0x2b1b || hs == 0x2b50 || hs == 0x231a) {
                    return true;
                }
                if (!isEmoji && source.length() > 1 && i < source.length() - 1) {
                    char ls = source.charAt(i + 1);
                    if (ls == 0x20e3) {
                        return true;
                    }
                }
            }
        }
        return isEmoji;
    }

    private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
                || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    /**
     * 过滤emoji 或者 其他非文字类型的字符
     * 
     * @param source
     * @return
     */
    public static String filterEmoji(String source) {
        if (StrKit.isBlank(source)) {
            return source;
        }
        StringBuilder buf = null;
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint)) {
                if (buf == null) {
                    buf = new StringBuilder(source.length());
                }
                buf.append(codePoint);
            }
        }
        if (buf == null) {
            return source;
        } else {
            if (buf.length() == len) {
                buf = null;
                return source;
            } else {
                return buf.toString();
            }
        }
    }
}

